﻿using Microsoft.EntityFrameworkCore;
using SMARTHOTEL.hotel;
using SMARTHOTEL.Pictures;
using SMARTHOTEL.Products;
using SMARTHOTEL.Users;
using System.Linq.Expressions;
using System.Reflection.Emit;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.Identity;
using Volo.Abp.SettingManagement.EntityFrameworkCore;


namespace SMARTHOTEL.EntityFrameworkCore;


[ConnectionStringName("Default")]
public class SMARTHOTELDbContext :
    AbpDbContext<SMARTHOTELDbContext>

{
    /* Add DbSet properties for your Aggregate Roots / Entities here. */

    #region Entities from the modules

    /* Notice: We only implemented IIdentityDbContext and ITenantManagementDbContext
     * and replaced them for this DbContext. This allows you to perform JOIN
     * queries for the entities of these modules over the repositories easily. You
     * typically don't need that for other modules. But, if you need, you can
     * implement the DbContext interface of the needed module and use ReplaceDbContext
     * attribute just like IIdentityDbContext and ITenantManagementDbContext.
     *
     * More info: Replacing a DbContext of a module ensures that the related module
     * uses this DbContext on runtime. Otherwise, it will use its own DbContext class.
     */


    #endregion
    public DbSet<RoomType> RoomTypes { get; set; }
    public DbSet<RoomMoney> RoomMoneys { get; set; }
    public DbSet<Stay> Stays { get; set; }
    public DbSet<StayRecord> StayRecords { get; set; }
    public DbSet<RoomNumber> RoomNumbers { get; set; }
    public DbSet<ProductLabel> ProductLabels { get; set; }
    public DbSet<Sort> Sorts { get; set; }
    public DbSet<Product> Products { get; set; }
    public DbSet<Reservation> eservations { get; set; }

    public DbSet<User> Users { get; set; }
    public DbSet<Permissions> Permissions { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<RolePermissions> RolePermissions { get; set; }
    public DbSet<UserRole> UserRoles { get; set; }


    public DbSet<Picture> Pictures { get; set; }
    public DbSet<PictureRelevance> PictureRelevances { get; set; }

    public SMARTHOTELDbContext(DbContextOptions<SMARTHOTELDbContext> options)
        : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        /* Include modules to your migration db context */

     


        builder.ConfigureSettingManagement();
        builder.ConfigureBackgroundJobs();
        builder.ConfigureAuditLogging();



    /* Configure your own tables/entities inside here */

    builder.Entity<RoomType>(b =>
        {
            b.HasQueryFilter(p => !p.IsDeleted);
            b.ToTable(SMARTHOTELConsts.DbTablePrefix + nameof(RoomType), SMARTHOTELConsts.DbSchema);
            b.ConfigureByConvention();
        });

        foreach (var entityType in builder.Model.GetEntityTypes())
        {
            var isDeletedProperty = entityType.ClrType.GetProperty("IsDeleted");
            // 双重验证：属性存在且类型为 bool
            if (isDeletedProperty != null && isDeletedProperty.PropertyType == typeof(bool))
            {
                // 动态构建 Lambda 表达式
                var parameter = Expression.Parameter(entityType.ClrType, "e");
                var propertyAccess = Expression.Property(parameter, isDeletedProperty);
                var filterCondition = Expression.Equal(propertyAccess, Expression.Constant(false));
                var lambda = Expression.Lambda(filterCondition, parameter);

                // 应用查询过滤器
                builder.Entity(entityType.ClrType).HasQueryFilter(lambda);
            }
        }
    }




}
